// Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use log::{error, trace};
use maestro_derive::MsgTag;
use ohmw_derive::{Decode, Encode};
use tokio::process::Command;

#[derive(Encode, Decode, MsgTag)]
#[msg_tag(case = "snake_case")]
pub struct GetEnvRet {
    pub host_desc: String,
    pub has_ros1: bool,
    pub has_ros2: bool,
    pub has_dora: bool,
    pub user_dir: String,
}

async fn run_command_and_log(cmd: &mut Command) -> bool {
    match cmd.output().await {
        Ok(output) => {
            trace!("command {:?}: {}", cmd, String::from_utf8_lossy(&output.stdout));
            true
        },
        Err(err) => {
            error!("command {:?} failed: {}", cmd, err);
            false
        },
    }
}

pub async fn get_env(enable_compress: bool) -> GetEnvRet {
    trace!("get_env: enabel_compress={}", enable_compress);
    let host_desc = if cfg!(target_env = "ohos") {
        "OHOS".to_string()
    } else  if cfg!(target_os = "linux") {
        "Linux".to_string()
    } else {
        "Unknown OS".to_string()
    };
    let user_dir = if cfg!(target_env = "ohos") {
        "/data".to_string()
    } else {
        std::env::var("HOME").unwrap_or_else(|_| "/".to_string())
    };
    GetEnvRet {
        host_desc,
        has_ros1: run_command_and_log(Command::new("rosversion").arg("-d")).await,
        has_ros2: std::env::var("ROS_DISTRO").is_ok_and(|distro| match distro.as_str() {
            "jazzy" => true, // TODO: more accurate check
            _ => false,
        }),
        has_dora: run_command_and_log(Command::new("dora").arg("-V")).await,
        user_dir,
    }
}
